package com.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zb.entity.ZjWorkSlaCondition;
import com.zb.entity.ZjWorkSlaConditionRemindEmp;
import com.zb.extend.WorkSlaConditionExtend;
import com.zb.extend.WorkSlaConditionRemindEmpExtend;
import com.zb.mapper.ZjWorkSlaConditionMapper;
import com.zb.service.ZjWorkSlaConditionRemindEmpService;
import com.zb.service.ZjWorkSlaConditionService;
import com.zb.vo.WorkSlaConditionVo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 工单SLA触发条件表 服务实现类
 * </p>
 *
 * @author WEN
 * @since 2024-02-04
 */
@Service
public class ZjWorkSlaConditionServiceImpl extends ServiceImpl<ZjWorkSlaConditionMapper, ZjWorkSlaCondition> implements ZjWorkSlaConditionService {
    @Resource
    private ZjWorkSlaConditionMapper workSlaConditionMapper;

    @Resource
    private ZjWorkSlaConditionRemindEmpService workSlaConditionRemindEmpService;

    // 保存或更新触发条件
    @Override
    public void save(Long custAccId, Long workSlaId, List<WorkSlaConditionVo> slaConditionVos) {
        List<ZjWorkSlaCondition> conditionList = getByWorkSlaId(workSlaId);
        if (CollectionUtil.isNotEmpty(conditionList)) {
            for (WorkSlaConditionVo vo : slaConditionVos) {
                if (null == vo.getId()) {
                    vo.setId(conditionList.stream().filter(f -> Objects.equals(f.getType(), vo.getType())).map(ZjWorkSlaCondition::getId).findFirst().orElse(null));
                }
            }
        }
        List<ZjWorkSlaCondition> adds = new ArrayList<>();
        List<ZjWorkSlaCondition> updates = new ArrayList<>();
        ZjWorkSlaCondition slaCondition = null;
        List<ZjWorkSlaConditionRemindEmp> slaRemindEmpList = new ArrayList<>();
        ZjWorkSlaConditionRemindEmp slaRemindEmp = null;
        for (WorkSlaConditionVo vo : slaConditionVos) {
            slaCondition = new ZjWorkSlaCondition();
            BeanUtil.copyProperties(vo, slaCondition);
            slaCondition.setBeforeOverTimeRemindEmpType(String.join(",", vo.getBeforeOverTimeRemindEmpType()));
            slaCondition.setAfterOverTimeRemindEmpType(String.join(",", vo.getAfterOverTimeRemindEmpType()));
            if (null != slaCondition.getId()) {
                updates.add(slaCondition);
            } else {
                slaCondition.setId(IdWorker.getId());
                slaCondition.setCustAccId(custAccId);
                slaCondition.setWorkSlaId(workSlaId);
                slaCondition.setBeforeOverTimeRemindTime(null == slaCondition.getBeforeOverTimeRemindTime()? 0 : slaCondition.getBeforeOverTimeRemindTime());
                slaCondition.setAfterOverTimeRemindTime(null == slaCondition.getAfterOverTimeRemindTime()? 0 : slaCondition.getAfterOverTimeRemindTime());
                adds.add(slaCondition);
            }
            if (vo.getBeforeOverTimeRemindEmpType().stream().anyMatch(f -> Objects.equals("2", f))) {
                Assert.isTrue(CollectionUtil.isNotEmpty(vo.getSlaBeforeOverTimeRemindEmpIds()), "超时前提醒人员的[指定人员]的具体人员不能为空");
                for (Long empId : vo.getSlaBeforeOverTimeRemindEmpIds()) {
                    slaRemindEmp = new ZjWorkSlaConditionRemindEmp();
                    slaRemindEmp.setId(IdWorker.getId());
                    slaRemindEmp.setCustAccId(custAccId);
                    slaRemindEmp.setWorkSlaId(workSlaId);
                    slaRemindEmp.setWorkSlaConditionId(slaCondition.getId());
                    slaRemindEmp.setType(1);
                    slaRemindEmp.setEmpId(empId);
                    slaRemindEmpList.add(slaRemindEmp);
                }
            }
            if (vo.getAfterOverTimeRemindEmpType().stream().anyMatch(f -> Objects.equals("2", f))) {
                Assert.isTrue(CollectionUtil.isNotEmpty(vo.getSlaAfterOverTimeRemindEmpIds()), "超时后提醒人员的[指定人员]的具体人员不能为空");
                for (Long empId : vo.getSlaAfterOverTimeRemindEmpIds()) {
                    slaRemindEmp = new ZjWorkSlaConditionRemindEmp();
                    slaRemindEmp.setId(IdWorker.getId());
                    slaRemindEmp.setCustAccId(custAccId);
                    slaRemindEmp.setWorkSlaId(workSlaId);
                    slaRemindEmp.setWorkSlaConditionId(slaCondition.getId());
                    slaRemindEmp.setType(2);
                    slaRemindEmp.setEmpId(empId);
                    slaRemindEmpList.add(slaRemindEmp);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(adds)) this.saveBatch(adds);
        if (CollectionUtil.isNotEmpty(updates)) this.updateBatchById(updates);
        workSlaConditionRemindEmpService.deleteByWorkSlaId(workSlaId);
        workSlaConditionRemindEmpService.saveBatch(slaRemindEmpList);
    }

    // 根据工单策略SLA ID获取触发条件
    @Override
    public List<ZjWorkSlaCondition> getByWorkSlaIds(List<Long> workSlaIds) {
        if (CollectionUtil.isEmpty(workSlaIds)) {
            return new ArrayList<>();
        }
        QueryWrapper<ZjWorkSlaCondition> wrapper = new QueryWrapper<>();
        wrapper.select("id", "work_sla_id", "type", "is_enabled AS enabled", "ageing_time",
                        "is_enable_before_over_time_remind AS enableBeforeOverTimeRemind", "before_over_time_remind_time", "before_over_time_remind_emp_type",
                        "is_enable_after_over_time_remind AS enableAfterOverTimeRemind", "after_over_time_remind_time", "after_over_time_remind_emp_type")
                .in("work_sla_id", workSlaIds);
        return this.list(wrapper);
    }

    // 根据工单策略SLA ID获取触发条件
    @Override
    public List<ZjWorkSlaCondition> getByWorkSlaId(Long workSlaId) {
        List<Long> workSlaIds = new ArrayList<>();
        workSlaIds.add(workSlaId);
        return getByWorkSlaIds(workSlaIds);
    }

    // 根据工单策略SLA ID获取触发条件
    @Override
    public List<WorkSlaConditionVo> getSlaConditionVosByWorkSlaId(Long workSlaId) {
        QueryWrapper<ZjWorkSlaCondition> wrapper = new QueryWrapper<>();
        wrapper.select("id", "work_sla_id", "type", "is_enabled AS enabled", "ageing_time",
                        "is_enable_before_over_time_remind AS enableBeforeOverTimeRemind", "before_over_time_remind_time", "before_over_time_remind_emp_type",
                        "is_enable_after_over_time_remind AS enableAfterOverTimeRemind", "after_over_time_remind_time", "after_over_time_remind_emp_type")
                .eq("work_sla_id", workSlaId);
        List<ZjWorkSlaCondition> conditionList = this.list(wrapper);
        List<ZjWorkSlaConditionRemindEmp> remindEmpList = workSlaConditionRemindEmpService.getByWorkSlaId(workSlaId);
        return conditionList.stream().map(con -> {
            WorkSlaConditionVo vo = new WorkSlaConditionVo();
            BeanUtil.copyProperties(con, vo);
            vo.setSlaBeforeOverTimeRemindEmpIds(remindEmpList.stream().filter(f -> f.getType() == 1 && Objects.equals(f.getWorkSlaConditionId(), con.getId()))
                    .map(ZjWorkSlaConditionRemindEmp::getEmpId).toList());
            vo.setSlaAfterOverTimeRemindEmpIds(remindEmpList.stream().filter(f -> f.getType() == 2 && Objects.equals(f.getWorkSlaConditionId(), con.getId()))
                    .map(ZjWorkSlaConditionRemindEmp::getEmpId).toList());
            return vo;
        }).toList();
    }

    // 根据工单策略SLA ID删除触发条件
    @Override
    public void deleteByWorkSlaIds(List<Long> workSlaIds) {
        if (CollectionUtil.isEmpty(workSlaIds)) {
            return;
        }
        QueryWrapper<ZjWorkSlaCondition> wrapper = new QueryWrapper<>();
        wrapper.in("work_sla_id", workSlaIds);
        this.remove(wrapper);
    }

    // 根据工单模块ID获取工单策略SLA
    @Override
    public List<WorkSlaConditionExtend> getByModuleIds(List<Long> moduleIds) {
        if (CollectionUtil.isEmpty(moduleIds)) {
            return new ArrayList<>();
        }
        List<WorkSlaConditionExtend> slaConditionList = workSlaConditionMapper.getByModuleIds(moduleIds);
        if (CollectionUtil.isEmpty(slaConditionList)) {
            return new ArrayList<>();
        }
        if (slaConditionList.stream().anyMatch(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(",")).contains("2"))) {
            List<WorkSlaConditionRemindEmpExtend> remindEmpExtendList = workSlaConditionRemindEmpService.getByWorkSlaConditionIds(slaConditionList.stream()
                    .filter(f -> Arrays.asList(f.getAfterOverTimeRemindEmpType().split(","))
                            .contains("2")).map(ZjWorkSlaCondition::getId).toList());
            slaConditionList.forEach(t -> {
                t.setWorkSlaConditionRemindEmpList(remindEmpExtendList.stream().filter(f -> Objects.equals(f.getWorkSlaConditionId(), t.getId())).toList());
            });
        }
        return slaConditionList;
    }
}
